/* eslint-disable camelcase */
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import cn from 'classnames';
import LogoSvg from './images/zoomeyePro.svg';
import BGJpg from './images/bg.jpeg';
import getWindowSize from '@util/get-window-size';
import { Button, message, Icon, Modal, Upload } from 'antd';
import { login, getCheckCode } from '@api/auth';
import _ from 'lodash';
import { bindActionCreators } from 'redux';
import { actions as authActions } from '@redux/reducer/auth';
import { uploadCert } from '@api/cert';
import { connect } from 'react-redux';
import rsa from '@util/rsa';
import './index.less';

class Login extends Component {
  constructor(props) {
    super(props);
    const size = getWindowSize();
    this.state = {
      username: '',
      password: '',
      checkCode: '',
      usernameError: '',
      passwordError: '',
      checkCodeError: '',
      certError: '',
      isLogining: false,
      certList: [],
      uploadCerting: false,
      passwordType: 'text',
      resetedPasswordType: false,
      checkCodeData: '',

      innerWidth: size.innerWidth,
      innerHeight: size.innerHeight
    };
  }

  componentDidMount() {
    window.addEventListener('resize', this.onWindowResize);
    this.getCheckCode();
  }
  componentWillUnmount() {
    window.removeEventListener('resize', this.onWindowResize);
  }

  onWindowResize = () => {
    this.setState({
      ...getWindowSize()
    });
  };

  onUsernameChange = e => {
    const value = e.target.value;
    const body = {
      username: value,
      usernameError: ''
    };
    if (!value) {
      body.usernameError = '用户名不能为空';
    }
    this.setState(body);
  };
  onPasswordChange = e => {
    const value = e.target.value;
    const body = {
      password: value,
      passwordError: ''
    };
    if (!value) {
      body.passwordError = '密码不能为空';
    }
    this.setState(body);
  };
  onCheckCodeChange = e => {
    const value = e.target.value;
    const body = {
      checkCode: value,
      checkCodeError: ''
    };
    if (!value) {
      body.checkCodeError = '验证码不能为空';
    }
    this.setState(body);
  };

  getCheckCode = () => {
    getCheckCode()
      .then(res => {
        let checkCodeData = _.get(res, 'data.data', '');
        this.setState({ checkCodeData });
      })
      .catch(() => {
        message.error('获取验证码失败，请稍后再试！');
      });
  };

  onLogin = () => {
    const {
      username,
      password,
      checkCode,
      usernameError,
      passwordError,
      checkCodeError
    } = this.state;
    const { setAuth, cert } = this.props;
    const publicKey = _.get(cert, 'publicKey', '');
    if (usernameError || passwordError || checkCodeError) {
      return;
    }
    let body = {};
    if (!username) {
      body.usernameError = '用户名不能为空!';
    }
    if (!password) {
      body.passwordError = '密码不能为空!';
    }
    if (!checkCode) {
      body.checkCodeError = '验证码不能为空!';
    }
    if (body.usernameError || body.passwordError || body.checkCodeError) {
      return this.setState(body);
    }
    this.setState({ isLogining: true });
    login({
      login: rsa.encrypt(username, publicKey),
      password: rsa.encrypt(password, publicKey),
      checkCode
    })
      .then(res => {
        const token = _.get(res, 'data.data.token');
        const user = _.get(res, 'data.data');
        setAuth({ token, user });
        message.success('登录成功');
      })
      .catch(({ message: messageInfo }) => {
        this.setState({ checkCode: '' });
        this.getCheckCode();
        message.error(messageInfo);
      })
      .finally(() => {
        this.setState({ isLogining: false });
      });
  };

  onKeyUp = e => {
    if (e.keyCode === 13) {
      this.onLogin();
    }
  };

  beforeUploadCert = file => {
    this.setState({ certList: [file], certError: '' });
    return false;
  };

  uploadCert = () => {
    const { certList } = this.state;
    if (!certList.length) {
      this.setState({
        certError: '请上传证书'
      });
      return;
    }
    const body = new FormData();
    body.append('file', certList[0]);
    this.setState({ uploadCerting: true });
    uploadCert(body)
      .then(() => {
        message.success('上传证书成功');
        // 加个延迟，防止请求间隔太短，证书还未解析
        setTimeout(() => {
          this.props
            .getCert()
            .then(() => {
              message.success('证书验证通过');
            })
            .catch(res => {
              const message = _.get(res, 'message', '获取证书失败');
              message.error(message);
            });
        }, 500);
      })
      .catch(() => {
        message.error('上传证书失败');
      })
      .finally(() => this.setState({ uploadCerting: false }));
  };

  removeCert = () => {
    this.setState({ certList: [] });
  };

  render() {
    const {
      username,
      password,
      checkCode,
      usernameError,
      passwordError,
      checkCodeError,
      isLogining,
      innerWidth,
      innerHeight,
      certList,
      certError,
      uploadCerting,
      passwordType,
      resetedPasswordType,
      checkCodeData
    } = this.state;

    const { cert, deviceId } = this.props;
    const hasCert = cert?.md5;
    const expired = Number(_.get(cert, 'expiry_time', 0)) * 1000 < Number(_.get(cert, 'now', 0));
    const isTrial = _.get(cert, 'is_trial', true);

    const style = {};
    const whr = innerWidth / innerHeight;
    // 背景图片宽高比
    const bgWhr = 3837 / 2160;
    if (whr >= bgWhr) {
      style.backgroundSize = '100% auto';
    } else {
      style.backgroundSize = 'auto 100%';
    }

    const uploadCertFooter = [
      <Button key="0" onClick={this.uploadCert} loading={uploadCerting} className="upload-cert-btn">
        确定
      </Button>
    ];

    const unCerted = !hasCert || (expired && isTrial);
    const oemId = _.get(cert, 'oem_id');
    const oemImgs = _.get(cert, 'oem_imgs', []);
    const logoImg = oemId ? (
      _.includes(oemImgs, 'product_logo.png') ? (
        <img src={`/oem/${oemId}/product_logo.png`} />
      ) : null
    ) : (
      <img src={LogoSvg} />
    );
    const bgImg = oemId ? (_.includes(oemImgs, 'bg.png') ? `/oem/${oemId}/bg.png` : '') : BGJpg;
    if (bgImg) {
      style.backgroundImage = `url(${bgImg})`;
    }

    return (
      <div
        className={cn('login', { 'login--un-cert': unCerted }, { oem: oemId })}
        onKeyUp={this.onKeyUp}
        style={style}
      >
        {!unCerted && (
          <Fragment>
            <div className="login-form">
              <div className="logo">{logoImg}</div>
              <div className="form">
                <div
                  className={cn('input', 'input-username', {
                    'input-username--error': Boolean(usernameError)
                  })}
                >
                  <input
                    className="input__field"
                    type="text"
                    value={username}
                    onChange={this.onUsernameChange}
                  />
                  <label
                    className={cn('input__label', { 'input__label--hidden': Boolean(username) })}
                  >
                    用户名
                  </label>
                  <div className="input__error">{usernameError}</div>
                </div>

                <div
                  className={cn('input', 'input-password', {
                    'input-password--error': Boolean(passwordError)
                  })}
                >
                  <input
                    className="input__field"
                    type={passwordType}
                    autoComplete="new-password"
                    onFocus={() => {
                      if (!resetedPasswordType) {
                        this.setState({ passwordType: 'password', resetedPasswordType: true });
                      }
                    }}
                    value={password}
                    onChange={this.onPasswordChange}
                  />
                  <div
                    className={cn('input__label', { 'input__label--hidden': Boolean(password) })}
                  >
                    密码
                  </div>
                  <div className="input__error">{passwordError}</div>
                  {resetedPasswordType && passwordType === 'text' ? (
                    <Icon
                      type="eye-invisible"
                      className="input__icon"
                      onClick={() => this.setState({ passwordType: 'password' })}
                    />
                  ) : (
                    <Icon
                      type="eye"
                      className="input__icon"
                      onClick={() => this.setState({ passwordType: 'text' })}
                    />
                  )}
                </div>

                <div
                  className={cn('input', 'input-checkcode', {
                    'input-checkcode--error': Boolean(checkCodeError)
                  })}
                >
                  <input
                    className="input__field"
                    type="text"
                    value={checkCode}
                    onChange={this.onCheckCodeChange}
                  />
                  <label
                    className={cn('input__label', { 'input__label--hidden': Boolean(checkCode) })}
                  >
                    验证码
                  </label>
                  <div
                    className="checkcode_img"
                    dangerouslySetInnerHTML={{ __html: checkCodeData }}
                    onClick={this.getCheckCode}
                    title="点击刷新"
                  />
                  <div className="input__error">{checkCodeError}</div>
                </div>

                <div className="login-btn">
                  <Button onClick={this.onLogin} loading={isLogining}>
                    登录
                  </Button>
                </div>
              </div>
            </div>
            <a
              style={{ color: '#fff' }}
              className="login__copyright"
              rel="noopener noreferrer"
              href={oemId ? _.get(cert, 'oem_company_site', '') : 'https://www.knownsec.com'}
              target="_blank"
            >
              ©&nbsp;
              {oemId ? _.get(cert, 'oem_company_name_cn', '') : '北京知道创宇信息技术股份有限公司'}
            </a>
          </Fragment>
        )}
        <Modal
          maskClosable={false}
          title={!hasCert ? '请先导入证书' : '证书过期，请更新'}
          visible={unCerted}
          closable={false}
          className={cn(
            'upload-cert-modal',
            'no-header-bottom-lines',
            'bottom-center',
            'padding-24'
          )}
          wrapClassName={cn(
            'upload-cert-modal__wrapper',
            {
              'upload-cert-modal__wrapper--width-100': whr >= bgWhr
            },
            {
              'upload-cert-modal__wrapper--height-100': whr < bgWhr
            }
          )}
          footer={uploadCertFooter}
          maskStyle={{ background: 'none' }}
        >
          <div className="cert-info">
            <div className="device-id">
              <label>设备标识</label>
              <div className="content">{deviceId || '暂空'}</div>
            </div>
            <div className="uploader">
              <label>证&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;书</label>
              <div className={cn('content', { 'upload-certed': certList.length })}>
                <Upload
                  beforeUpload={this.beforeUploadCert}
                  onRemove={this.removeCert}
                  accept=".lic"
                  fileList={certList}
                >
                  <Button style={{ width: 200 }}>
                    <Icon type="upload" /> 点击上传“.lic”格式文件
                  </Button>
                </Upload>
                <div className={cn('cert-error', { 'cert-error--enable': Boolean(certError) })}>
                  {certError}
                </div>
              </div>
            </div>
          </div>
        </Modal>
      </div>
    );
  }
}

Login.propTypes = {
  history: PropTypes.object,
  setAuth: PropTypes.func,
  cert: PropTypes.object,
  deviceId: PropTypes.object,
  getCert: PropTypes.func
};

const mapStateToProps = state => {
  return {
    deviceId: _.get(state, 'auth.deviceId', ''),
    cert: _.get(state, 'auth.cert', {})
  };
};

const mapDispatchToProps = dispatch => {
  return {
    ...bindActionCreators(authActions, dispatch)
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Login);
